fn variablebind() {
    let v1 = 1;
    let mut v2 = 2;
    let _v3 = 3;

    // v1 = 2;      // error: cannot assign twice to immutable variable
    v2 += 1;
    println!("----------- Test Variable Bind -----------");
    println!("v1 = {}", v1);
    println!("v2 = {}", v2);
}

fn deconstruct() {
    let (v1, v2, mut v3) : (bool, i32, i32) = (false, 2, 3);
    v3 += 1;
    println!("-----------  Test Deconstruct  -----------");
    println!("v1 = {}, v2 = {}, v3 = {}", v1, v2, v3);

    let (v4, v5, v6, v7, v8): (i32, i32, i32, i32, i32);
    (v4, v5) = (1, 2);
    [v6, .., v7, _] = [1, 2, 3, 4, 5];
    v8 = 6;
    println!("v4 = {}, v5 = {}, v6 = {}, v7 = {}, v8 = {}", v4, v5, v6, v7, v8);
}

fn constant() {
    const MAX_POINTS: u32 = 100_000;
    println!("------------  Test Constant   ------------");
    println!("MAX_POINTS = {}", MAX_POINTS);
}

fn shadowing() {
    let x = 5;
    let x = x + 1;

    println!("------------  Test Shadowing   -----------");
    {
        let x = x * 2;
        println!("x = {}", x);
    }
    println!("x = {}", x);
}

fn main() {
    variablebind();
    deconstruct();
    constant();
    shadowing();
}
